﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentManagement.ViewModels;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.Data;
using SchoolPointe.RelatedContent.Models;
using SchoolPointe.RelatedContent.ViewModels;
using SchoolPointe.RelatedContent.Enums;
using SchoolPointe.RelatedContent.Services;

namespace SchoolPointe.RelatedContent.Settings
{
    public class RelatedContentPartSettings
    {
        public RelatedContentPartSettings(SettingsDictionary settings)
        {
            var relationships = new List<RelatedContentRelationship>();
            foreach (var key in settings.Keys)
            {
                var relationship = new RelatedContentRelationship(settings[key]);
                relationship.Identifier = key.Replace("RelatedContentPartSettings.", "");
                relationships.Add(relationship);
            }
            this.Relationships = relationships.AsEnumerable();
        }

        public IEnumerable<RelatedContentRelationship> Relationships { get; private set; }
        
    }

    public class  RelatedContentSettingsHooks : ContentDefinitionEditorEventsBase
    {
        private readonly IContentDefinitionManager _contentDefinitionManager;
        private readonly IRelatedContentService _relatedContentService;
        private string _typeName;
        private string _typeDisplayName;

        public RelatedContentSettingsHooks(IContentDefinitionManager contentDefinitionManager, IRelatedContentService relatedContentService)
        {
            _contentDefinitionManager = contentDefinitionManager;
            _relatedContentService = relatedContentService;
        }

        public override IEnumerable<TemplateViewModel> TypeEditor(ContentTypeDefinition definition)
        {
            _typeDisplayName = definition.DisplayName;
            _typeName = definition.Name;
            yield break;            
        }

  
        public override IEnumerable<TemplateViewModel> TypePartEditor(ContentTypePartDefinition definition)
        {
            if (definition.PartDefinition.Name != "RelatedContentPart")
                yield break;

            var settings = new RelatedContentPartSettings(definition.Settings);
            var model = new RelatedContentPartSettingsViewModel
                            {
                                ParentTypeName = _typeDisplayName,
                                PossibleContentTypes = _contentDefinitionManager.ListTypeDefinitions().ToList(),
                                Relationships = settings.Relationships.ToList()
                            };

            yield return DefinitionTemplate(model);
        }

        public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel)
        {
            if (builder.Name != "RelatedContentPart")
                yield break;

            var model = new RelatedContentPartSettingsViewModel();
            model.PossibleContentTypes = _contentDefinitionManager.ListTypeDefinitions().ToList();
            if (updateModel.TryUpdateModel(model, "RelatedContentPartSettingsViewModel", null, null))
            {
                foreach (var relationship in model.Relationships)
                {
                    if (string.IsNullOrEmpty(relationship.Identifier))
                    {
                        var newIdentifier = relationship.Name.Replace(" ", "-");
                        if (model.Relationships.Any(r => r.Identifier == newIdentifier))
                        {
                            int counter = 2;
                            while (model.Relationships.Any(r => r.Identifier == newIdentifier + "_" + counter.ToString()))
                            {
                                counter++;
                            }
                            newIdentifier = newIdentifier + "_" + counter.ToString();
                        }
                        relationship.Identifier = newIdentifier;
                    }
                    string key = "RelatedContentPartSettings." + relationship.Identifier;
                    builder.WithSetting(key, relationship.ToJson());
                }

                //remove deleted keys
                var type = _contentDefinitionManager.GetTypeDefinition(_typeName);
                var part = type.Parts.Single(p => p.PartDefinition.Name == "RelatedContentPart");
                foreach (var key in part.Settings.Keys)
                {
                    if (!model.Relationships.Select(r => "RelatedContentPartSettings." + r.Identifier).Contains(key))
                        builder.WithSetting(key, null);
                }
            }
            yield return DefinitionTemplate(model);
        }
        
    }
}